profile, p & 1, (p >> 1) & 0x1ff, (p >> 10) & 0x1ff, (p >> 19) & 0x1ff);
}
-void rtl8380_sds_rst(int mac)
-{
- u32 offset = (mac == 24) ? 0 : 0x100;
-
- sw_w32_mask(1 << 11, 0, RTL838X_SDS4_FIB_REG0 + offset);
- sw_w32_mask(0x3, 0, RTL838X_SDS4_REG28 + offset);
- sw_w32_mask(0x3, 0x3, RTL838X_SDS4_REG28 + offset);
- sw_w32_mask(0, 0x1 << 6, RTL838X_SDS4_DUMMY0 + offset);
- sw_w32_mask(0x1 << 6, 0, RTL838X_SDS4_DUMMY0 + offset);
- pr_debug("SERDES reset: %d\n", mac);
-}
-
-int rtl8380_sds_power(int mac, int val)
-{
- u32 mode = (val == 1) ? 0x4 : 0x9;
- u32 offset = (mac == 24) ? 5 : 0;
-
- if ((mac != 24) && (mac != 26)) {
- pr_err("%s: not a fibre port: %d\n", __func__, mac);
- return -1;
- }
-
- sw_w32_mask(0x1f << offset, mode << offset, RTL838X_SDS_MODE_SEL);
-
- rtl8380_sds_rst(mac);
-
- return 0;
-}
phy_modify(phydev, 0, BMCR_RESET, BMCR_RESET);
}
-/* Read the link and speed status of the 2 internal SGMII/1000Base-X
- * ports of the RTL838x SoCs
- */
-__attribute__((unused))
-static int rtl8380_read_status(struct phy_device *phydev)
-{
- int err;
-
- err = genphy_read_status(phydev);
-
- if (phydev->link) {
- phydev->speed = SPEED_1000;
- phydev->duplex = DUPLEX_FULL;
- }
-
- return err;
-}
-
/* Read the link and speed status of the 2 internal SGMII/1000Base-X
* ports of the RTL8393 SoC
*/
return 0;
}
-static int rtl8380_configure_serdes(struct phy_device *phydev)
-{
- u32 v;
- u32 sds_conf_value;
- int i;
- struct fw_header *h;
- u32 *rtl8380_sds_take_reset;
- u32 *rtl8380_sds_common;
- u32 *rtl8380_sds01_qsgmii_6275b;
- u32 *rtl8380_sds23_qsgmii_6275b;
- u32 *rtl8380_sds4_fiber_6275b;
- u32 *rtl8380_sds5_fiber_6275b;
- u32 *rtl8380_sds_reset;
- u32 *rtl8380_sds_release_reset;
-
- phydev_info(phydev, "Detected internal RTL8380 SERDES\n");
-
- h = rtl838x_request_fw(phydev, &rtl838x_8218b_fw, FIRMWARE_838X_8380_1);
- if (!h)
- return -1;
-
- if (h->magic != 0x83808380) {
- phydev_err(phydev, "Wrong firmware file: magic number mismatch.\n");
- return -1;
- }
-
- rtl8380_sds_take_reset = (void *)h + sizeof(struct fw_header) + h->parts[0].start;
-
- rtl8380_sds_common = (void *)h + sizeof(struct fw_header) + h->parts[1].start;
-
- rtl8380_sds01_qsgmii_6275b = (void *)h + sizeof(struct fw_header) + h->parts[2].start;
-
- rtl8380_sds23_qsgmii_6275b = (void *)h + sizeof(struct fw_header) + h->parts[3].start;
-
- rtl8380_sds4_fiber_6275b = (void *)h + sizeof(struct fw_header) + h->parts[4].start;
-
- rtl8380_sds5_fiber_6275b = (void *)h + sizeof(struct fw_header) + h->parts[5].start;
-
- rtl8380_sds_reset = (void *)h + sizeof(struct fw_header) + h->parts[6].start;
-
- rtl8380_sds_release_reset = (void *)h + sizeof(struct fw_header) + h->parts[7].start;
-
- /* Back up serdes power off value */
- sds_conf_value = sw_r32(RTL838X_SDS_CFG_REG);
- pr_info("SDS power down value: %x\n", sds_conf_value);
-
- /* take serdes into reset */
- i = 0;
- while (rtl8380_sds_take_reset[2 * i]) {
- sw_w32(rtl8380_sds_take_reset[2 * i + 1], rtl8380_sds_take_reset[2 * i]);
- i++;
- udelay(1000);
- }
-
- /* apply common serdes patch */
- i = 0;
- while (rtl8380_sds_common[2 * i]) {
- sw_w32(rtl8380_sds_common[2 * i + 1], rtl8380_sds_common[2 * i]);
- i++;
- udelay(1000);
- }
-
- /* internal R/W enable */
- sw_w32(3, RTL838X_INT_RW_CTRL);
-
- /* SerDes ports 4 and 5 are FIBRE ports */
- sw_w32_mask(0x7 | 0x38, 1 | (1 << 3), RTL838X_INT_MODE_CTRL);
-
- /* SerDes module settings, SerDes 0-3 are QSGMII */
- v = 0x6 << 25 | 0x6 << 20 | 0x6 << 15 | 0x6 << 10;
- /* SerDes 4 and 5 are 1000BX FIBRE */
- v |= 0x4 << 5 | 0x4;
- sw_w32(v, RTL838X_SDS_MODE_SEL);
-
- pr_info("PLL control register: %x\n", sw_r32(RTL838X_PLL_CML_CTRL));
- sw_w32_mask(0xfffffff0, 0xaaaaaaaf & 0xf, RTL838X_PLL_CML_CTRL);
- i = 0;
- while (rtl8380_sds01_qsgmii_6275b[2 * i]) {
- sw_w32(rtl8380_sds01_qsgmii_6275b[2 * i + 1],
- rtl8380_sds01_qsgmii_6275b[2 * i]);
- i++;
- }
-
- i = 0;
- while (rtl8380_sds23_qsgmii_6275b[2 * i]) {
- sw_w32(rtl8380_sds23_qsgmii_6275b[2 * i + 1], rtl8380_sds23_qsgmii_6275b[2 * i]);
- i++;
- }
-
- i = 0;
- while (rtl8380_sds4_fiber_6275b[2 * i]) {
- sw_w32(rtl8380_sds4_fiber_6275b[2 * i + 1], rtl8380_sds4_fiber_6275b[2 * i]);
- i++;
- }
-
- i = 0;
- while (rtl8380_sds5_fiber_6275b[2 * i]) {
- sw_w32(rtl8380_sds5_fiber_6275b[2 * i + 1], rtl8380_sds5_fiber_6275b[2 * i]);
- i++;
- }
-
- i = 0;
- while (rtl8380_sds_reset[2 * i]) {
- sw_w32(rtl8380_sds_reset[2 * i + 1], rtl8380_sds_reset[2 * i]);
- i++;
- }
-
- i = 0;
- while (rtl8380_sds_release_reset[2 * i]) {
- sw_w32(rtl8380_sds_release_reset[2 * i + 1], rtl8380_sds_release_reset[2 * i]);
- i++;
- }
-
- pr_info("SDS power down value now: %x\n", sw_r32(RTL838X_SDS_CFG_REG));
- sw_w32(sds_conf_value, RTL838X_SDS_CFG_REG);
-
- pr_info("Configuration of SERDES done\n");
-
- return 0;
-}
-
static int rtl8390_configure_serdes(struct phy_device *phydev)
{
phydev_info(phydev, "Detected internal RTL8390 SERDES\n");
return 0;
}
-static int rtl838x_serdes_probe(struct phy_device *phydev)
-{
- int addr = phydev->mdio.addr;
-
- if (soc_info.family != RTL8380_FAMILY_ID)
- return -ENODEV;
- if (addr < 24)
- return -ENODEV;
-
- return 0;
-}
-
static int rtl8393_serdes_probe(struct phy_device *phydev)
{
int addr = phydev->mdio.addr;
.write_mmd = rtl821x_write_mmd,
.write_page = rtl821x_write_page,
},
- {
- PHY_ID_MATCH_MODEL(PHY_ID_RTL8218B_I),
- .name = "Realtek RTL8380 SERDES",
- .features = PHY_GBIT_FIBRE_FEATURES,
- .probe = rtl838x_serdes_probe,
- .read_page = rtl821x_read_page,
- .write_page = rtl821x_write_page,
- .suspend = genphy_suspend,
- .resume = genphy_resume,
- .read_status = rtl8380_read_status,
- },
{
PHY_ID_MATCH_MODEL(PHY_ID_RTL8393_I),
.name = "Realtek RTL8393 SERDES",